<?php

namespace services\base;

use api\modules\v1\forms\base\ProjectForm;
use common\components\Service;
use common\helpers\CommonHelper;
use common\helpers\RedisHelper;
use common\models\base\Project;
use services\buss\AccountsService;
use services\buss\DevicesService;
use services\buss\DoctorsService;
use services\log\LogMemberOpService;
use services\member\AttrService;
use services\member\MemberProjectService;
use services\member\MemberService;
use Yii;

/**
 * Class ProjectService
 * @package services\base
 */
class ProjectService extends Service
{
    /**
     * 项目列表
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getListPage(array $params = [], int $page = 0, int $pageSize = 0): array
    {
        $query = Project::find()->alias('p')
            ->select([
                'p.*',
            ])
            ->where(['p.id' => array_column(MemberService::getAllProjectListCondition(), 'value')]);
        if (isset($params['project_name']) && $params['project_name']) {
            $query->andWhere(['like', 'p.project_name', $params['project_name']]);
        }
        if (isset($params['status']) && is_numeric($params['status'])) {
            $query->andWhere(['p.status' => $params['status']]);
        } else {
            $query->andWhere(['p.status' => [Project::STATUS_INVALID, Project::STATUS_ENABLE]]);
        }
        // 排序
        $order = [];
        /*if (isset($params['order_column']) && $params['order_column']) {
            $sort = isset($params['order_sort']) && $params['order_sort'] == 'asc' ? SORT_ASC : SORT_DESC;
            switch ($params['order_column']) {
                case 'doctor_num':
                case 'account_num':
                case 'devices_num':
                case 'member_num':
                    $order["{$params['order_column']}"] = $sort;
                    break;
                default:
                    break;
            }
            $order && $order['p.id'] = SORT_DESC;
        }*/
        empty($order) && $order = ['p.status' => SORT_DESC, 'p.sort' => SORT_ASC, 'p.id' => SORT_ASC];

        return $this->getListPageRes($query, $page, $pageSize, $order);
    }

    /**
     * 格式化列表
     * @param array $data
     * @return array
     */
    public function getListPageFormat(array $data = []): array
    {
        $ids = array_column($data, 'id');
        $doctorMap = DoctorsService::getStaticsNumByProject($ids);
        $accountMap = AccountsService::getStaticsNumByProject($ids);
        $deviceMap = DevicesService::getStaticsNumByProject($ids);
        $memberMap = MemberProjectService::getStaticsNumByProject($ids);

        $list = [];
        foreach ($data as $row) {
            $adminNames = [];
            $memberIds = MemberProjectService::getAdminMemberIdsByProjectId($row['id']);
            foreach ($memberIds as $memberId) {
                $member = RedisHelper::getMember($memberId);
                $adminNames[] = $member->realname;
            }

            $list[] = [
                'id' => $row['id'],
                'project_name' => $row['project_name'],
                'doctor_num' => $doctorMap[$row['id']]['doctor_num'] ?? 0,
                'account_num' => $accountMap[$row['id']]['account_num'] ?? 0,
                'devices_num' => $deviceMap[$row['id']]['devices_num'] ?? 0,
                'member_num' => $memberMap[$row['id']]['member_num'] ?? 0,
                'sort' => $row['sort'],
                'status_str' => Project::$statuss[$row['status']] ?? '',
                'admin_names' => $adminNames,
//                'created_at_str' => DateHelper::timestampToDate($row['created_at']),
            ];
        }
        return $list;
    }

    /**
     * 列表筛选项
     * @return array
     */
    public function getSelectCondition(): array
    {
        return [
            'status' => self::getStatusCondition(),
        ];
    }

    /**
     * 状态下拉筛选项
     * @return array[]
     */
    public static function getStatusCondition(): array
    {
        return [
            ['value' => Project::STATUS_ENABLE, 'label' => Project::$statuss[Project::STATUS_ENABLE]],
            ['value' => Project::STATUS_INVALID, 'label' => Project::$statuss[Project::STATUS_INVALID]],
        ];
    }

    /**
     * 项目详情
     * @param array $params
     * @return array
     */
    public function getInfo(int $id): array
    {
        $data = [];
        // 项目信息
        $project = Project::findOne($id);
        if ($project) {
            $data = [
                'id' => $project->id,
                'project_name' => $project->project_name,
                'status' => $project->status,
                'sort' => $project->sort,
            ];
        }

        return $data;
    }

    /**
     * 项目管理员详情
     * @param array $params
     * @return array
     */
    public function getAdminInfo(int $id): array
    {
        $data = [];
        // 项目信息
        $project = Project::findOne($id);
        if (empty($project)) {
            return CommonHelper::api(422, '项目不存在');
        }
        $memberIds = MemberProjectService::getAdminMemberIdsByProjectId($project->id);
        $member = MemberService::getEditCondition(MemberProjectService::getMemberIdsByProjectId($project->id));

        return [
            'member_ids' => $memberIds,
            'condition' => [
                'member' => $member
            ],
        ];
    }

    /**
     * 根据Ids获取项目列表【正常】
     * @param array|null $ids
     * @param int|array|null $orId
     * @return Project[]
     */
    public static function getEnableListByIds(?array $ids = null, $orId = null): array
    {
        $query = Project::find()
            ->select(['*'])
            ->where([
                'status' => [Project::STATUS_ENABLE],
            ]);
        if (!is_null($ids)) {
            $query->andWhere(['id' => $ids]);
        }
        if ($orId) {
            $query->orWhere([
                'id' => $orId,
                'status' => [Project::STATUS_INVALID, Project::STATUS_ENABLE],
            ]);
        }
        return $query->orderBy(['sort' => SORT_ASC, 'id' => SORT_ASC])->all();
    }

    /**
     * 根据Ids获取项目列表【禁用 + 正常】
     * @param array|null $ids
     * @return Project[]
     */
    public static function getNormalListByIds(?array $ids = null, $orId = []): array
    {
        $query = Project::find()
            ->select(['*'])
            ->where([
                'status' => [Project::STATUS_INVALID, Project::STATUS_ENABLE],
            ]);
        if (!is_null($ids)) {
            $query->andWhere(['id' => $ids]);
        }
        if ($orId) {
            $query->orWhere([
                'id' =>$orId,
                'status' => [Project::STATUS_INVALID, Project::STATUS_ENABLE],
            ]);
        }
        return $query->orderBy(['sort' => SORT_ASC, 'id' => SORT_ASC])->all();
    }


    /**
     * 根据Ids获取所有项目列表【禁用 + 正常 + 删除】
     * @param array|null $ids
     * @return Project[]
     */
    public static function getAllListByIds(?array $ids = null, $orId = []): array
    {
        $query = Project::find()
            ->select(['*']);
        if (!is_null($ids)) {
            $query->andWhere(['id' => $ids]);
        }
        if ($orId) {
            $query->orWhere([
                'id' =>$orId,
            ]);
        }
        return $query->orderBy(['sort' => SORT_ASC, 'id' => SORT_ASC])->all();
    }

    /**
     * 根据Ids获取项目列表【禁用 + 正常】
     * @param array $projectIds
     * @return Project[]
     */
    public static function getNormalCacheListByIds(array $projectIds): array
    {
        $projectArr = [];
        foreach ($projectIds as $projectId) {
            $project = RedisHelper::getProject($projectId);
            if (empty($project) || $project->status == Project::STATUS_DELETE) {
                continue;
            }
            $projectArr[] = $project;
        }
        return $projectArr;
    }

    /**
     * 获取下拉列表筛选项
     * @return array
     */
    public static function getListCondition(): array
    {
        return CommonHelper::getListCondition(self::getNormalListByIds(), ['value_column' => 'id', 'label_column' => 'project_name']);
    }

    /**
     * 详情绑定项目列表
     * @param int|array|null $orId
     * @return array
     */
    public static function getEditCondition($orId = null): array
    {
        // 人员项目编辑筛选
        $data = MemberService::getProjectEditCondition($orId);

        $ids = MemberService::getMemberProjectIds();
        $dataFormat = [];
        foreach ($data as $row) {
            $row['disabled'] = is_null($ids) || in_array($row['value'], $ids) ? 0 : 1;
            $dataFormat[] = $row;
        }
        return $dataFormat;
    }

    /**
     * 编辑项目
     * @param Project $project
     * @param ProjectForm $model
     * @return Project
     * @throws \Exception
     */
    public static function editModel(Project $project, ProjectForm $model): Project
    {
        $project->project_name = $model->project_name;
        $project->status = $model->status;
        $project->sort = $model->sort;
        $project->operation_id = Yii::$app->user->identity->member_id;
        $project->operation_name = Yii::$app->user->identity->member->realname;
        $project->saveAndCheckResult();

        return $project;
    }

    /**
     * 新增项目
     * @param ProjectForm $model
     * @return array
     */
    public function create(ProjectForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.新增项目
            $project = new Project();
            $project = self::editModel($project, $model);

            // 2.日志
            LogMemberOpService::createProjectLog($model, $project);

            $transaction->commit();
            return ['id' => $project->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 编辑项目
     * @param ProjectForm $model
     * @return array
     */
    public function edit(ProjectForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.更新项目
            $oldProject = new Project();
            $oldProject->setAttributes($model->getProject()->getAttributes());
            $project = self::editModel($model->getProject(), $model);

            // 2.日志
            LogMemberOpService::createProjectLog($model, $project, $oldProject);

            // 3.更新缓存
            RedisHelper::setProject($project);

            $transaction->commit();
            return ['id' => $project->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 删除项目
     * @param ProjectForm $model
     * @return array
     */
    public function delete(ProjectForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.更新项目
            $project = $model->getProject();
            $project->status = Project::STATUS_DELETE;
            $project->operation_id = Yii::$app->user->identity->member_id;
            $project->operation_name = Yii::$app->user->identity->member->realname;
            $project->saveAndCheckResult();

            // 2.日志
            LogMemberOpService::createProjectLog($model, $project);

            // 3.解绑人员项目
            AttrService::unBindProject($project->id);

            // 4.更新缓存
            RedisHelper::delProject($project->id);

            $transaction->commit();

            return ['id' => $project->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 设置项目管理员
     * @param ProjectForm $model
     * @return array
     */
    public function editAdmin(ProjectForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.日志
            $project = $model->getProject();
            if (LogMemberOpService::createProjectLog($model, $project)) {
                // 2.更新项目管理员
                MemberProjectService::editProjectAdmin($project->id, array_column($model->getMemberList(), 'id'));
            }

            $transaction->commit();

            return ['id' => $project->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }
}
